﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using StreetsOfRageStyleGame.Enums;

namespace StreetsOfRageStyleGame
{
    public class CharacterSprite
    {
        protected const int START_POSITION_X = 125;
        protected const int START_POSITION_Y = 245;
        protected const int CHARACTER_SPEED = 160;
        protected const int MOVE_UP = -1;
        protected const int MOVE_DOWN = 1;
        protected const int MOVE_LEFT = -1;
        protected const int MOVE_RIGHT = 1;

        protected float timer = 0f;
        protected const float interval = 100f;

        protected Vector2 Position { get; set; }
        protected Vector2 mDirection { get; set; }
        protected Vector2 mSpeed { get; set; }

        protected KeyboardState mPreviousKeyboardState { get; set; }

        protected SpriteSheet spriteSheet1 { get; set; }

        protected String currentFrame { get; set; }
        protected Object currentFrameEnum { get; set; }
        protected int currentFrameNumber { get; set; }

        protected GraphicsDeviceManager graphicsDeviceManager { get; set; }

        protected Character character { get; set; }
        protected CharacterAlignment characterAlignment { get; set; }
        protected CharacterState currentState { get; set; }
        protected CharacterDirection currentDirection { get; set; }
        protected int characterHitPoints { get; set; }

        protected Vector2 colisionBoxPosition { get; set; }
        protected Vector2 colisionBoxSize { get; set; }

        protected Rectangle collisionBox { get; set; }

        protected Keys lastKeyPressed { get; set; }
        protected int ticksSinceLastKeyPress { get; set; }

        public CharacterSprite() {
            Position = new Vector2(100, 100);
            mDirection = Vector2.Zero;
            mSpeed = Vector2.Zero;

            lastKeyPressed = Keys.None;
            ticksSinceLastKeyPress = 0;
        }

        public CharacterSprite(GraphicsDeviceManager graphicsDeviceManager, Character character, CharacterAlignment characterAlignment, int characterHitPoints)
        {
            this.graphicsDeviceManager = graphicsDeviceManager;
            this.characterHitPoints = characterHitPoints;
            this.character = character;
            this.characterAlignment = characterAlignment;

            Position = new Vector2(100, 100);
            mDirection = Vector2.Zero;
            mSpeed = Vector2.Zero;

            lastKeyPressed = Keys.None;
            ticksSinceLastKeyPress = 0;
        }



        public void LoadContent(ContentManager theContentManager)
        {
            spriteSheet1 = new SpriteSheet();
            spriteSheet1.Sheet = theContentManager.Load<Texture2D>(Enum.GetName(typeof(Character), character));
            spriteSheet1.Map = theContentManager.Load<Dictionary<string, Rectangle>>(Enum.GetName(typeof(Character), character) + "Map");

            currentState = CharacterState.Still;
            currentDirection = CharacterDirection.Right;
            currentFrame = Enum.GetName(typeof(StillSprite), StillSprite.Still1);
            currentFrameEnum = StillSprite.Still1;
            currentFrameNumber = 1;

        }

        public void Update(GameTime theGameTime)
        {
            KeyboardState aCurrentKeyboardState = Keyboard.GetState();

            mPreviousKeyboardState = aCurrentKeyboardState;

            //Increase the timer by the number of milliseconds since update was last called
            timer += (float)theGameTime.ElapsedGameTime.TotalMilliseconds;

            //Check the timer is more than the chosen interval


            if (timer > interval)
            {
                currentFrame = GetNextFrame();
                //Reset the timer
                timer = 0f;
            }

            //ticksSinceLastKeyPress++;

            //If we are on the last frame, reset back to the one before the first frame (because currentFrame++ is called next so the next frame will be 1!)

            Position += mDirection * mSpeed * (float)theGameTime.ElapsedGameTime.TotalSeconds;
            UpdateMovement(aCurrentKeyboardState);
        }

        public void UpdateMovement(KeyboardState aCurrentKeyboardState)
        {


        }

        public void Draw(SpriteBatch spriteBatch)
        {
            Texture2D texture = spriteSheet1.Sheet;

            Rectangle sp = spriteSheet1[GetCurrentFrameName()];
            if (sp != null)
            {
                if (currentDirection == CharacterDirection.Left)
                {
                    spriteBatch.Draw(texture, Position, spriteSheet1[GetCurrentFrameName()], Color.White, 0, new Vector2(), 1.45f, SpriteEffects.None, 0);
                }
                else
                {
                    spriteBatch.Draw(texture, Position, spriteSheet1[GetCurrentFrameName()], Color.White, 0, new Vector2(), 1.45f, SpriteEffects.FlipHorizontally, 0);
                }
            }
        }

        public String GetCurrentFrameName()
        {
            String returnValue = "";

            if (currentState == CharacterState.Still)
            {
                returnValue = Enum.GetName(typeof(StillSprite), (StillSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Walking)
            {
                returnValue = Enum.GetName(typeof(WalkingSprite), (WalkingSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Running)
            {
                returnValue = Enum.GetName(typeof(RunningSprite), (RunningSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Punch)
            {
                returnValue = Enum.GetName(typeof(PunchSprite), (PunchSprite)currentFrameNumber);
            }

            if(returnValue.Equals(""))
            {
                returnValue = Enum.GetName(typeof(StillSprite), (StillSprite)currentFrameNumber);
            }
            return returnValue;
        }

        public String GetNextFrame()
        {
            if (currentState == CharacterState.Still)
            {
                if (currentFrameNumber >= (int)Enum.GetValues(typeof(StillSprite)).Cast<StillSprite>().Max())
                {
                    currentFrameNumber = 1;
                }
                else
                {
                    currentFrameNumber++;
                }

                return Enum.GetName(typeof(StillSprite), (StillSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Walking)
            {
                if (currentFrameNumber >= (int)Enum.GetValues(typeof(WalkingSprite)).Cast<WalkingSprite>().Max())
                {
                    currentFrameNumber = 1;
                }
                else
                {
                    currentFrameNumber++;
                }

                return Enum.GetName(typeof(WalkingSprite), (WalkingSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Running)
            {
                if (currentFrameNumber >= (int)Enum.GetValues(typeof(RunningSprite)).Cast<RunningSprite>().Max())
                {
                    currentFrameNumber = 1;
                }
                else
                {
                    currentFrameNumber++;
                }

                return Enum.GetName(typeof(RunningSprite), (RunningSprite)currentFrameNumber);
            }
            else if (currentState == CharacterState.Punch)
            {
                if (currentFrameNumber >= (int)Enum.GetValues(typeof(PunchSprite)).Cast<PunchSprite>().Max() || ticksSinceLastKeyPress > 1000)
                {
                    currentFrameNumber = 1;
                }
                else
                {
                    currentFrameNumber++;
                }

                return Enum.GetName(typeof(PunchSprite), (PunchSprite)currentFrameNumber);
            }
            else
            {
                return "";
            }
        }

        public void ChangeCharacterState(CharacterState state)
        {
            if (currentState != state)
            {
                currentState = state;
                currentFrameNumber = 1;
            }
        }

        public void MoveCharacter()
        {

        }

        public Boolean CheckForColision(Rectangle rectangle)
        {
            return collisionBox.Intersects(rectangle);
        }
    }
}
